package com.myproject.utils;

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.Date;

/**
 * 时间处理工具类
 * 
 * <p>提供常用的时间操作方法，基于Java 8的java.time包实现，线程安全。</p>
 */
public class TimeUtils {

    // 常用时间格式
    public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
    public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
    public static final String DEFAULT_TIME_FORMAT = "HH:mm:ss";

    private TimeUtils() {
        // 私有构造方法防止实例化
    }

    /**
     * 获取当前时间
     * @return 当前LocalDateTime
     */
    public static LocalDateTime now() {
        return LocalDateTime.now();
    }

    /**
     * 获取当前时间戳（毫秒）
     * @return 当前时间戳
     */
    public static long currentTimestamp() {
        return System.currentTimeMillis();
    }

    /**
     * 格式化时间为字符串
     * @param dateTime 时间对象
     * @param pattern 格式模式
     * @return 格式化后的时间字符串
     */
    public static String format(LocalDateTime dateTime, String pattern) {
        return dateTime.format(DateTimeFormatter.ofPattern(pattern));
    }

    /**
     * 格式化时间为字符串（使用默认格式）
     * @param dateTime 时间对象
     * @return 格式化后的时间字符串
     */
    public static String format(LocalDateTime dateTime) {
        return format(dateTime, DEFAULT_DATE_TIME_FORMAT);
    }

    /**
     * 解析字符串为时间对象
     * @param dateTimeStr 时间字符串
     * @param pattern 格式模式
     * @return 解析后的LocalDateTime
     */
    public static LocalDateTime parse(String dateTimeStr, String pattern) {
        return LocalDateTime.parse(dateTimeStr, DateTimeFormatter.ofPattern(pattern));
    }

    /**
     * 解析字符串为时间对象（使用默认格式）
     * @param dateTimeStr 时间字符串
     * @return 解析后的LocalDateTime
     */
    public static LocalDateTime parse(String dateTimeStr) {
        return parse(dateTimeStr, DEFAULT_DATE_TIME_FORMAT);
    }

    /**
     * 时间戳转LocalDateTime
     * @param timestamp 时间戳（毫秒）
     * @return LocalDateTime
     */
    public static LocalDateTime timestampToDateTime(long timestamp) {
        return LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp), ZoneId.systemDefault());
    }

    /**
     * LocalDateTime转时间戳
     * @param dateTime 时间对象
     * @return 时间戳（毫秒）
     */
    public static long dateTimeToTimestamp(LocalDateTime dateTime) {
        return dateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
    }

    /**
     * 旧Date转LocalDateTime
     * @param date 旧Date对象
     * @return LocalDateTime
     */
    public static LocalDateTime dateToDateTime(Date date) {
        return LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
    }

    /**
     * LocalDateTime转旧Date
     * @param dateTime 时间对象
     * @return Date
     */
    public static Date dateTimeToDate(LocalDateTime dateTime) {
        return Date.from(dateTime.atZone(ZoneId.systemDefault()).toInstant());
    }

    /**
     * 计算两个时间之间的天数差
     * @param start 开始时间
     * @param end 结束时间
     * @return 天数差
     */
    public static long daysBetween(LocalDateTime start, LocalDateTime end) {
        return ChronoUnit.DAYS.between(start, end);
    }

    /**
     * 计算两个时间之间的小时差
     * @param start 开始时间
     * @param end 结束时间
     * @return 小时差
     */
    public static long hoursBetween(LocalDateTime start, LocalDateTime end) {
        return ChronoUnit.HOURS.between(start, end);
    }

    /**
     * 增加天数
     * @param dateTime 原始时间
     * @param days 要增加的天数
     * @return 增加后的时间
     */
    public static LocalDateTime plusDays(LocalDateTime dateTime, long days) {
        return dateTime.plusDays(days);
    }

    /**
     * 减少天数
     * @param dateTime 原始时间
     * @param days 要减少的天数
     * @return 减少后的时间
     */
    public static LocalDateTime minusDays(LocalDateTime dateTime, long days) {
        return dateTime.minusDays(days);
    }

    /**
     * 判断时间是否在某个时间范围内
     * @param dateTime 要判断的时间
     * @param start 范围开始时间
     * @param end 范围结束时间
     * @return 是否在范围内
     */
    public static boolean isBetween(LocalDateTime dateTime, LocalDateTime start, LocalDateTime end) {
        return dateTime.isAfter(start) && dateTime.isBefore(end);
    }

    /**
     * 获取当天的开始时间（00:00:00）
     * @param dateTime 时间对象
     * @return 当天的开始时间
     */
    public static LocalDateTime getStartOfDay(LocalDateTime dateTime) {
        return dateTime.toLocalDate().atStartOfDay();
    }

    /**
     * 获取当天的结束时间（23:59:59）
     * @param dateTime 时间对象
     * @return 当天的结束时间
     */
    public static LocalDateTime getEndOfDay(LocalDateTime dateTime) {
        return dateTime.toLocalDate().atTime(LocalTime.MAX);
    }
}